
package org.ccay.excel.importer.service.impl.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.util.StringUtil;
import org.ccay.core.xml.BigXmlReadHandler;
import org.ccay.core.xml.BigXmlWriteHandler;
import org.ccay.core.xml.XmlHelper;
import org.dom4j.Element;
import org.dom4j.ElementPath;
public class ExcelXmlAppenderHandler extends BigXmlReadHandler{
	/**
	 * 是否已写入开始SheetData标签
	 */
	private boolean isWriteBeginSheetData = false;
	/**
	 * 是否写入结束SheetData标签
	 */
	private boolean isWriteEndSheetData = false;
	
	/**
	 * 是否自定义列
	 */
	private boolean customCol = true;
	
	/**
	 * 当前当前标签元素
	 */
	private String currElement;
	/**
	 * TODO 以后可能换数组   一个sheet 有多块数据
	 * 标题行  
	 */
	private int titleRowIndex;
	/**
	 * 错误列
	 */
	private String addColNo;
	/**
	 * shee名称
	 */
	private String sheetName;
	
	public void setSheetName(String sheetName) {
		this.sheetName = sheetName;
	}

	/**
	 * 处理数据的type
	 */
	private String errorDisplay;
	/**
	 * 写的对象
	 */
	BigXmlWriteHandler xmlWriteHandler = null;
	/**
	 * sheet错误数据
	 */
	Map<String,StringBuffer> sheetErrorData = null;
	/**
	 * sheet节点
	 */
	Element sheetElment = XmlHelper.createElement("sheetData");
	StringBuffer msg = null;
	/**
	 * 日志对象
	 */
	private ILogger logger = CcayLoggerFactory.getLogger(ExcelXMLFileAppender.class);
	
	
	ExcelXmlAppenderHandler(InputStream imputStream,String[] xmlElementPath,BigXmlWriteHandler xmlWriteHandler) {
		super(xmlElementPath,imputStream);
		this.xmlWriteHandler = xmlWriteHandler;
	}

	public void setTitleRowIndex(int titleRowIndex) {
		this.titleRowIndex = titleRowIndex;
	}

	public void setAddColNo(String addColNo) {
		this.addColNo = addColNo;
	}

	public void setSheetErrorData(Map<String, StringBuffer> sheetErrorData) {
		this.sheetErrorData = sheetErrorData;
	}

	public void setErrorDisplay(String errorDisplay) {
		this.errorDisplay = errorDisplay;
	}

	@Override
	public void onEnd(ElementPath elementPath) {
		Element userElement = elementPath.getCurrent();
		/**
		 * 如果操作的是行 那么需要判断是否增加数据
		 */
		try {
			if("row".equals(userElement.getName())){
				int rowIndex = Integer.valueOf(userElement.attributeValue("r"));
				if(rowIndex == titleRowIndex){
					onTitleRow(userElement);	
				}
				onErrorRow(userElement,rowIndex);
			}
			
			this.xmlWriteHandler.write(userElement);
			currElement = userElement.getName();
			/**
			 * 如果操作的是列 那么打开sheet
			 */
//			if("cols".equals(userElement.getName())){
//				this.xmlWriteHandler.writeOpen(this.sheetElment);
//			}
		} catch (IOException e) {
			logger.error(e);
		}	
		//切记，从内存中清除,否则大文件导致内存溢出
		userElement.detach();
	}
	
	/**
	 * 处理标题行
	 * @param userElement
	 * Created：2013-9-16
	 * @author chaowangbang
	 */
	private void onTitleRow(Element userElement){
		//如过增加的列是null 那么使用追加的方式
		if(StringUtil.isNullOrEmpty(addColNo)){
			Element temp =  (Element) userElement.elements().get(userElement.elements().size()-1);
			String lastColNo = temp.attributeValue("r");
			addColNo = StringUtil.charNext(lastColNo.substring(0,lastColNo.indexOf(titleRowIndex+"")));
			customCol = false;
		}
		//增加判断如果已经存在标签,则直接添加数据 wx244051 2016-06-01
		if (customCol) {
			List<Element> list = userElement.content();
			for (int i = 0; i < list.size(); i++) {
				String colIndex = list.get(i).attributeValue("r");
				Element currElement = list.get(i);
				if ((addColNo+titleRowIndex).compareTo(colIndex) < 0) {
					Element element = userElement.addElement("c");
					element.addAttribute("r", addColNo+titleRowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText("Error");
					userElement.remove(element);
					list.add(i, element);
					return;
				}
				if ((addColNo+titleRowIndex).compareTo(colIndex) == 0) {
					currElement.addAttribute("r", addColNo+titleRowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText("Error");
					return;
				}
			}
		}
		//这里使用一长串增加  减少dom自动生成的一些东西
		userElement.addElement("c").addAttribute("r", addColNo+titleRowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText("Error");
	}
	/**
	 * 处理错误行
	 * @param userElement
	 * @param rowIndex
	 * Created：2013-9-16
	 * @author chaowangbang
	 */
	private void onErrorRow(Element userElement,int rowIndex){
		msg = sheetErrorData.get(sheetName+"|-|"+rowIndex);
		if(msg == null){
			return;
		}
		if(msg != null){
			//增加判断如果已经存在标签,则直接添加数据 wx244051 2016-06-01
			if (customCol) {
				List<Element> list = userElement.content();
				for (int i = 0; i < list.size(); i++) {
					String colIndex = list.get(i).attributeValue("r");
					Element currElement = list.get(i);
					if ((addColNo+rowIndex).compareTo(colIndex) < 0) {
						Element element = userElement.addElement("c");
						element.addAttribute("r", addColNo+rowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText(msg.toString());
						userElement.remove(element);
						list.add(i, element);
						return;
					}
					if ((addColNo+rowIndex).compareTo(colIndex) == 0) {
						currElement.addAttribute("r", addColNo+rowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText(msg.toString());
						return;
					}
				}
			}
			//增加错误信息
			userElement.addElement("c").addAttribute("r", addColNo+rowIndex).addAttribute("t", "inlineStr").addElement("is").addElement("t").setText(msg.toString());
		}
	}
	
	@Override
	public void onStart(ElementPath elementPath) {
		Element userElement = elementPath.getCurrent();
		/**
		 * 关闭出sheet
		 */
//		if("phoneticPr".equals(userElement.getName())){
//			try {
//				this.xmlWriteHandler.writeClose(this.sheetElment);
//			} catch (IOException e) {
//				logger.error(e);
//			}
//		}
		//修改写入sheetData元素标记写入规则，避免添加错误的标签
		if("row".equals(userElement.getName()) && !isWriteBeginSheetData){
			try {
				isWriteBeginSheetData = true;
				this.xmlWriteHandler.writeOpen(this.sheetElment);
			} catch (IOException e) {
				logger.error(e);
			}
		}
		if (isWriteBeginSheetData && "row".equals(currElement) && !isWriteEndSheetData && !"row".equals(userElement.getName())) {
			try {
				isWriteEndSheetData = true;
				this.xmlWriteHandler.writeClose(this.sheetElment);
			} catch (IOException e) {
				logger.error(e);
			}
		}
		super.onStart(elementPath);
	}
	
}
